package api

import (
	"context"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"project05_web/src/cache"
	"project05_web/src/forms"
	"project05_web/src/global"
	"project05_web/src/middlewares"
	"project05_web/src/models"
	"project05_web/src/proto"
	utilss "project05_web/src/utils"
	utils "project05_web/src/utils/Email"
	"strings"
	"time"
)

// 发送注册验证码
func GetValidateCode(c *gin.Context) {
	// 获取目的邮箱
	em := []string{c.Param("email")}

	//发送验证码，并将验证码id和email存入redis
	vCode, err := utils.SendEmailValidate(em, 1)
	if err != nil {
		log.Println(err)
		c.JSON(http.StatusBadRequest, gin.H{
			"status":           400,
			"msg":              "验证码发送失败",
			"ERROR-CONTROLLER": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":    "验证码发送成功",
		"status": 200,
		"vCode":  vCode,
	})
	return
}

// 获取邮箱登录验证码
func GetLoginValidateCode(c *gin.Context) {
	// 获取目的邮箱
	em := []string{c.Param("email")}

	//发送验证码，并将验证码id和email存入redis
	vCode, err := utils.SendEmailValidate(em, 2)
	if err != nil {
		log.Println(err)
		c.JSON(http.StatusBadRequest, gin.H{
			"status":           400,
			"msg":              "验证码发送失败",
			"ERROR-CONTROLLER": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":    "验证码发送成功",
		"status": 200,
		"vCode":  vCode,
	})
	return
}

// ValidateEmailCode
// @Title ValidateEmailCode
// @Description  验证邮箱验证码，并注册用户。
// @Author hyy 2022-03-05 18:19:18
// @Param c type description
func ValidateEmailCode(c *gin.Context) {

	//检验邮箱是否合法
	var user forms.CreateUserByEmail
	err := c.ShouldBindJSON(&user)
	if err != nil {
		log.Println(err.Error())
		c.JSON(http.StatusBadRequest, gin.H{
			"status":           400,
			"msg":              "注册失败，json解析失败",
			"ERROR-CONTROLLER": err.Error(),
		})
		return
	}
	myEmail := user.Email
	// 默认用户权限为2
	if user.RoleId == 0 {
		user.RoleId = 3
	}

	// 验证结构体字段

	// 对密码进行加密

	// 通过邮箱获取在redis中绑定的id
	id, err := global.RedisDb.Get(context.Background(), myEmail).Result()
	myResp := strings.Split(id, "&amp")
	if myResp[1] != "emailtoregister" {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg":  "验证码失效",
			"data": nil,
			"code": 400,
		})
		return
	}

	id = myResp[0]
	if err != nil {
		log.Println(err.Error())
		c.JSON(http.StatusBadRequest, gin.H{
			"status":           400,
			"msg":              "Redis获取vCode失败",
			"ERROR-CONTROLLER": err.Error(),
		})
		return
	}
	//通过id获取到redis中的验证码
	vCode := user.VCode
	res := cache.RedisStore{}.Verify(id, vCode, true)
	if res {
		resp, errs := global.UserClient.CreateSmsUser(context.Background(), &proto.SmsInfo{
			Phone:    "",
			Email:    user.Email,
			Password: user.Password,
			Identify: user.Identify,
			RoleId:   int32(user.RoleId),
		})

		if errs != nil {
			SwitchGrpcErrorToHttp(err, c)
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"msg":  "注册成功",
			"data": resp,
			"code": 200,
		})
	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"status": 400,
			"msg":    "验证失败，验证码已失效",
		})
		return
	}
}

// 验证邮箱验证码并登录
func ValidateEmailCodeToLogin(c *gin.Context) {
	//定义一个邮箱登录结构体
	EmailFrom := forms.EmailLoginFrom{}
	//将请求映射到结构体当中
	err := c.ShouldBind(&EmailFrom)
	if err != nil {
		c.JSON(http.StatusBadRequest, utilss.ErrResp(err))
		return
	}
	//检验邮箱是否合法
	myEmail := EmailFrom.Email
	myVCode := EmailFrom.VCode
	// 通过邮箱获取在redis中绑定的id
	id, err := global.RedisDb.Get(context.Background(), myEmail).Result()
	if err != nil {
		log.Println(err.Error())
		c.JSON(http.StatusBadRequest, gin.H{
			"status":           400,
			"msg":              "验证码不存在或过期",
			"ERROR-CONTROLLER": err.Error(),
		})
		return
	}

	//验证id是否合法
	myResp := strings.Split(id, "&amp")
	if myResp[1] != "emailtologin" {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg":  "验证码失效",
			"data": nil,
			"code": 400,
		})
		return
	}
	id = myResp[0]

	//通过id获取到redis中的验证码
	vCode := myVCode
	res := cache.RedisStore{}.Verify(id, vCode, true)
	if res {
		//获取token
		user, errs := global.UserClient.GetUserByEmail(context.Background(), &proto.EmailRequest{Email: myEmail})
		if errs != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"msg":  "邮箱获取用户失败",
				"data": nil,
				"code": 500,
			})
		}
		j := middlewares.NewJWT()
		claims := models.CustomClaims{
			ID:          uint(user.Id),
			UserName:    user.UserName,
			AuthorityId: uint(user.RoleID),
			StandardClaims: jwt.StandardClaims{
				ExpiresAt: time.Now().Unix() + 60*60*24*30,
				Issuer:    "Jo",
				NotBefore: time.Now().Unix(),
			},
		}
		token, err := j.CreateToken(claims)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"msg":  "生成验证码失败",
				"data": nil,
				"code": 500,
			})
		}
		//发送token
		c.JSON(http.StatusOK, gin.H{
			"msg": "登录成功",
			"data": gin.H{
				"user":    user,
				"x-token": token,
			},
			"code": 200,
		})
	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"status": 400,
			"msg":    "验证失败，验证码已失效",
		})
		return
	}
}
